Skip to content

docs: onboarding and trust makeover#181

Merged
jeremi merged 29 commits into
mainfrom
docs/makeover
Jul 2, 2026
Merged

docs: onboarding and trust makeover#181
jeremi merged 29 commits into
mainfrom
docs/makeover

Conversation

@jeremi

@jeremi jeremi commented Jul 2, 2026

Copy link
Copy Markdown
Member

Supersedes #167 and #174: merges both, fixes their review findings, and completes the target information architecture.

What changed

Onboarding. The homepage routes in three bands (fast path, two products, security strip). see-it-live splits into a five-minute zero-install Quickstart and a credential tour where a new reader first meets an SD-JWT VC. The Relay tutorial keeps #167's rewrite with the platform-fallback guidance restored; the standalone-Notary tutorial states its real prerequisites; the DHIS2 page is reshaped to the tutorial pattern with a "Make it yours" section.

Trust path. New Security section: REQ-anchored overview (absorbing the trust-posture page), hardening checklist grounded in RS-SEC-G Section 9 and the deployment-assurance gates, vulnerability-reporting how-to mirroring SECURITY.md, and the self-assessment and OpenSSF evidence pages moved in. The six explanation pages from #174 are kept with their style debt cleared (~172 em dashes, ~108 bold-led list items) and zero factual drift.

Navigation. Sidebar restructured: Get started is the first-run journey in reading order; the generated Relay, Notary, and Manifest groups lift to top-level product sections; Integrations and Concepts replace the old group names. Redirects cover every moved or split page; a stale /start/quickstart/ → / redirect that would have shadowed the new page is removed.

Accuracy. All three Tier-C claims verified against the implementation (holder-binding default, signing algorithms, audit fields). Writing the trust pages surfaced #178 (Notary audit omitted the spec-required scopes); it is fixed on main, merged here, and the interim caveats are pruned.

Review notes (security-sensitive)

Documentation only; no runtime behavior changes. The Security section pages and the trust/security explanation pages carry status: draft pending Tier-C maintainer sign-off; claim-by-claim code evidence is available in the branch history and review threads. Please give the security overview, hardening checklist, threat model, and known-limitations pages a maintainer read before lifting draft.

Verification

Full docs/site gate green at HEAD: npm run check (generate with zero drift, docset, content, markdown, style, OpenAPI, config vocabulary, tutorial drift dry-run at the pinned command counts, SVG, build of 216 pages plus archives, llms, SEO, and 263,845 built internal links). npm test passes. Independent reviews applied: an expert pass over the docs-authoring skills and a reader-persona pass over the six key pages.

jeremi and others added 21 commits June 28, 2026 01:50
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Adds the trust-spine pilot explanation at
explanation/records-stay-home.mdx — the quality exemplar for the
documentation effort. It explains how an institution proves facts from
registries it already holds without the records leaving: what stays
inside the boundary, what crosses it, the three disclosure modes
(value / predicate / redacted), and an honest statement of what the
design does and does not guarantee.

Resolves the shippable frontmatter TODO by setting owner to the
registry-docs area (matching sibling explanation pages) and quotes
last_reviewed for house-style consistency.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gfv6Eurtn4CzfnxLpNL2gP
Signed-off-by: Claude <noreply@anthropic.com>
Make the Related links archive-safe (../../spec/... instead of root-
relative /spec/...), unblocking the check:links:built CI gate that
rejects archived pages linking outside their version.

Tighten two Tier-C security claims to match RS-SEC-G and the page's own
honesty thesis:
- the published public key verifies a signed credential or signed
  result, not "a result" in general (default results are provenance-
  tagged, not signed);
- describe the unauthenticated surface accurately (liveness/readiness
  probes, public verification keys, credential-issuance discovery
  metadata) while keeping the strong rule that anything touching a
  record or claim requires authentication.

Declare the SD-JWT VC standard in standards_referenced.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gfv6Eurtn4CzfnxLpNL2gP
Signed-off-by: Claude <noreply@anthropic.com>
… tutorial

Add five reviewer/operator-facing explanation pages and wire them into the
sidebar (a new "Trust & security" group, plus the disclosure page and the
records-stay-home pilot under Explanation):

- Trust posture and security guarantees — a plain-language overview with an
  at-a-glance posture table.
- Disclosure modes and computed answers — the three modes and what each one
  reveals.
- Data minimization and purpose limitation — the privacy / DPO view.
- Threat model — boundaries, assets, threats, and residual risks.
- Known limitations and non-guarantees — the canonical limits hub the other
  pages link to instead of restating.

Refresh the Relay tutorial (publish-spreadsheet-secured-registry-api) with a
clearer framing, the exact problem+json codes (auth.missing_credential /
auth.scope_denied / auth.purpose_required), and a "what you built" recap, on
top of its existing verified command output. The sh-command count is
unchanged, so the tutorial drift check still holds.

All pages follow the house style (second person, sentence-case headings, no
inline spec citations — the specs are linked at the foot of each page), and
every load-bearing security/privacy claim was re-verified against both the
RS-* specs and the implementation. The content stages of `npm run check`
pass (frontmatter, Vale, markdown, openapi lint, tutorial drift, build,
llms, links, seo).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011U1jTj594nGXhR2r9BzWqm
Signed-off-by: Claude <noreply@anthropic.com>
Apply seven code-grounded accuracy corrections from review of this PR. Each
was verified against the notary crates and the generated OpenAPI before editing:

- Trust posture: broaden the anonymous-route list — it also includes
  credential-issuer discovery, the OID4VCI wallet-flow endpoints, the docs,
  public credential-status reads, and credential type metadata, not only
  probes and public keys.
- Known limitations: qualify the absolute "no credential revocation service" —
  the RS-* specs define no revocation flow, but an optional, off-by-default
  credential-status surface can mark a credential revoked; and name the
  not_full_issuer flag to the /.well-known/evidence-service capability-discovery
  document rather than the OID4VCI credential-issuer metadata.
- Threat model: admin routes ARE documented in the generated OpenAPI (the
  prior "not in the public OpenAPI document" claim was wrong); standalone mode
  still returns HTTP 501 for runtime reload.
- Data minimization: field minimization is driven by the configured
  binding.fields (plus lookup/freshness fields), not auto-derived from the rule.
- records-stay-home (pilot): the audit-record claim no longer implies Notary
  records exercised scopes (Relay does; Notary's record does not), and holder
  binding is qualified as per-profile (default unbound; the wallet path binds).

check:style, check:markdown, build, and check:links all pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011U1jTj594nGXhR2r9BzWqm
Signed-off-by: Claude <noreply@anthropic.com>
Apply nine code-verified corrections so four claim-classes read consistently
and accurately across the trust/privacy pages (and the records-stay-home pilot):

- Revocation: requalify the absolute "no revocation service" as no spec-defined
  revocation flow plus an optional, off-by-default credential-status surface
  (public GET + admin POST status endpoints) that can mark a credential
  `revoked`. (data-minimization, threat-model, records-stay-home; matches the
  earlier known-limitations fix.)
- Anonymous surface: broaden "only probes + keys" to the full auth-exempt set
  (probes, public verification keys, credential-issuer discovery, OID4VCI
  wallet-flow endpoints, docs, public credential-status reads, type metadata),
  and note the federation route is exempt from the API-key/OIDC middleware but
  still requires a verified peer-signed JWS, so it is not anonymous.
  (threat-model, records-stay-home.)
- value-mode gradation: keep "exactly three modes, no fourth", but note that
  within `value` mode an object-valued claim can have configured fields
  redacted (`redaction_fields`), so `value` is not always all-or-nothing.
  (disclosure-modes.)
- Caller choice: the policy bounds which modes are allowed; within the allowed
  set the caller can request one (refused with claim.disclosure_not_allowed
  otherwise), and the default applies when none is requested — corrects the
  "never the caller's choice" overstatement. (disclosure-modes, trust-posture,
  records-stay-home.)

check:style, check:markdown, build, and check:links all pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011U1jTj594nGXhR2r9BzWqm
Signed-off-by: Claude <noreply@anthropic.com>
…-granularity claims

Four code-verified refinements from continued review:

- known limitations (revocation): only the admin status endpoint (requires the
  registry:notary:admin scope) marks a credential revoked; the public status
  endpoint reads status. Corrected the wording that implied the public endpoint
  could revoke.
- known limitations (delegated attestation): reframed the absolute "no
  delegated-attestation issuance" — the OID4VCI transaction-token path is
  rejected, but direct issuance via /v1/credentials is supported when the stored
  evaluation is delegated-attestation and the relationship allow-lists the profile.
- disclosure modes (redacted + CCCEV): note a current renderer limitation — the
  CCCEV JSON-LD renderer emits cccev:isConformantTo: false for a redacted result
  instead of omitting it, so the no-outcome guarantee is not fully upheld in that
  render. (Tracked as a product issue.)
- data minimization (SD-JWT granularity): selective disclosure is at the claim
  (or configured-projection) level — each claim is one disclosure carrying its
  whole value, so an object-valued claim is revealed as a unit unless an explicit
  projection splits it.

check:style, check:markdown, build, and check:links all pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011U1jTj594nGXhR2r9BzWqm
Signed-off-by: Claude <noreply@anthropic.com>
…implementation

Six code-verified refinements where an absolute "limit" is actually conditional:

- data minimization: claim-level purpose constraints (the claim's permitted
  purposes and the deployment allowed-purposes list) are enforced before a
  source read even with no binding matching policy; only the binding-level
  gating is missing in that case.
- known limitations (federation): replay protection defaults to in-memory, but
  a Redis-backed shared replay store is available for multi-instance
  deployments — "no shared replay storage" was too absolute.
- known limitations (Relay): signed response credentials are config-gated via
  provenance, not Cargo-feature-gated; and with provenance enabled Relay can
  attach its own VC-JWT signed response credential (it still does not issue
  Notary's SD-JWT VC credentials).
- known limitations (reload): standalone /admin/v1/reload returns 501 and
  non-swappable changes need a restart, but governed config apply and the
  file-watch signer hot-apply some changes (signing-key rotation, auth-policy
  swaps) without one.
- threat model + known limitations (duplicate ids): duplicate claim ids are not
  rejected at load and are never reported — the runtime lookup returns the first
  match, so a later duplicate is silently shadowed (corrected the earlier "surface
  at runtime" wording on both pages).

check:style, check:markdown, build, and check:links all pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011U1jTj594nGXhR2r9BzWqm
Signed-off-by: Claude <noreply@anthropic.com>
…el with limitations

Two new code-verified corrections plus three threat-model alignments:

- records-stay-home (read-in-place): in snapshot mode (the default) Relay
  materializes a projected copy into its local cache (cache_dir). There is still
  no write-back to the source and no external handoff, but a cached copy exists,
  with its own retention/access considerations — distinguished from "no copy".
- disclosure modes (exists/predicate): an `exists` claim returns `true` when a
  record matches, but a subject with no matching record returns
  `evidence.not_available` (collapsed to a single public reason by default), not
  a bare `false` — absence is no-evidence, not a negative result.
- threat model: align with the limitations page on three points the threat
  model still stated absolutely — shared replay storage is supported (Redis),
  Relay signed response credentials are config-gated via provenance (not
  Cargo-gated), and some config/key changes hot-apply without a restart.

check:style, check:markdown, build, and check:links all pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011U1jTj594nGXhR2r9BzWqm
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>

# Conflicts:
#	docs/site/src/content/docs/tutorials/publish-spreadsheet-secured-registry-api.mdx
…rial lead

The standalone-Notary tutorial now states its dependency on the local
Relay project (or an operator-owned Registry Data API source) instead of
implying independence. Restores the unsupported-platform install fallback
as a troubleshooting row. Reshapes the DHIS2 opener to the tutorial
pattern and promotes deployment adaptation into a Make-it-yours section.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Removes em dashes and bold-led list items, merges duplicate lead
paragraphs, and fixes reference words across the six trust and security
explanation pages. No factual claim, qualifier, or hedge changed;
Tier-C sign-off on the content itself is still pending.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
The implementation gap tracked in #178 is fixed on main
(EvidenceAuditEvent.scopes_used), so the known-limitations entry and the
two per-page caveats come out.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Security overview absorbs the trust-posture page (its at-a-glance table
and framing over the REQ-anchored draft), new hardening checklist and
vulnerability-reporting how-tos, and the self-assessment and OpenSSF
evidence pages move under security/. All new pages carry status: draft
pending Tier-C maintainer sign-off.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
The zero-install Relay reads become the five-minute Quickstart; the
Notary issuance flow becomes its own credential tour, the first place a
new reader sees a privacy-preserving credential.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Get started becomes the first-run journey in reading order; the generated
Relay, Notary, and Manifest groups lift to top-level product sections;
Integrations and Concepts replace the old group names; the Security rail
gathers the overview, threat model, limitations hub, hardening, reporting,
and evidence pages. Redirects cover the moved and split pages, the stale
quickstart-to-home redirect is gone, and remaining cross-links point at
the new slugs. The orphaned HomeLanding component is removed.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Glossary link and journey ordering on the homepage, drop the unsupported
flagship line, show the 403 body the quickstart prose interprets, replace
the credential tour's cross-page anchors with page links and drop its
duplicated caveat, gloss holder binding and delegated evaluation on the
security overview and eSignet on the hardening checklist, and mark the
release-verification example asset as a placeholder with its expected
output.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
jeremi added 5 commits July 2, 2026 13:25
configuration.md pointed at jeremi/registry-relay at a frozen SHA for
metadata, development, and provenance docs; relative links track the
monorepo and let the docs-site sync rewrite them to site routes.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
…orepo

Notary README and manifest docs linked jeremi/registry-notary and
jeremi/registry-manifest at frozen SHAs; relative links track the
monorepo. The client SDK guide's Cargo, pip, and pnpm coordinates now
name registrystack/registry-stack with the products/notary/bindings
paths. The sidecar guide's platform link follows the doc's move to
products/platform/docs.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
24 repo docs that product pages already linked (Relay API guide, ops
runbook, metadata, provenance, OpenFn and standards adapter guides;
Notary API reference, capability matrix, operator and adapter guides;
Manifest ITB/SEMIC validation) join the sync allowlist, so their links
rewrite to site routes instead of bouncing readers to GitHub markdown.
Contributor docs (development, perf, specs) intentionally stay GitHub
links. The two security-assurance docs stay unpublished until their
pre-monorepo container-signing claims are corrected; tracked in #186.
New entries are excluded from the old-repo beta docsets and verified
present at the v0.8.1 through v0.8.3 archive refs.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
The docs-site style guide bans em dashes and its Vale gate now covers
synced product pages; these two source docs were the only pages with
error-level hits.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
- Run Vale on synced product pages: drop the !**/products/** glob from
  check:style. The 40 synced pages had zero error-level hits after the
  companion notary prose fix, so the gate stays green while gaining the
  backstop it lacked.
- Wire evidence_gap into the pipeline: generate-data.mjs rejects
  non-boolean values and StandardsTable renders the flag next to the
  claim level (ink weight, no new color), so the style guide's
  instruction is enforced and visible instead of a bare convention.
- Align the code-link rule with shipped practice: pin to a release tag
  or commit SHA; every load-bearing link on the site pins v0.8.3 tags,
  which the old SHA-only wording outlawed.
- Fix the AGENTS.md pointer to the design doc (the relative path never
  resolved in this repo; the doc is maintained alongside the repository,
  not published in it) and the Latin vale rule's swapped %s message,
  which told writers to use 'e.g.' instead of spelling it out.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
jeremi added 2 commits July 2, 2026 14:17
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
@jeremi jeremi marked this pull request as ready for review July 2, 2026 07:25
@jeremi jeremi merged commit c595e84 into main Jul 2, 2026
10 checks passed
@jeremi jeremi deleted the docs/makeover branch July 2, 2026 07:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a26e06381

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// to their new homes so old links and search results keep resolving.
redirects: {
'/start/': internalRedirect('/'),
'/start/see-it-live/': internalRedirect('/start/quickstart/'),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Redirect retired live-demo links to the credential tour

The deleted /start/see-it-live/ page used to cover both the Relay read and the Notary credential issuance flow, and repo-wide search still finds product docs linking to it as the Notary hosted walkthrough (for example products/notary/docs/README.md says it lets users watch Notary issue a credential). With this redirect, those links now land on the Relay-only quickstart, so users following the Notary “See it live” path no longer reach the credential issuance tour. Redirect the retired route to /start/credential-tour/ for that flow, or update the remaining Notary links to the new page.

Useful? React with 👍 / 👎.

Comment on lines +18 to +20
# The raw bearer keys live in secrets/local.env. Public config keeps only the
# fingerprint env var names, so it can be shared without leaking credentials.
# If you rotate a generated key, update the raw key and fingerprint together.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep generated fingerprints compatible with the pinned image

In generated projects that use the bundled compose file, this config is run by the still-pinned Relay image digest da9332..., unchanged from the v0.8.3 template. That binary's config model requires fingerprint.commitment, while this template now generates fingerprint env var names only, so registryctl start/Compose users will fail config parsing before Relay starts. Either update the image digest to a build that removed commitments or keep emitting commitments for the pinned image.

Useful? React with 👍 / 👎.

output/
.gitignore
```
The sample workbook has three sheets:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Point the tutorial at a build with the new sample

This page still has readers install v0.8.3 above, but the three-sheet workbook and aggregate/Application steps are documented in crates/registryctl/CHANGELOG.md under [Unreleased]; the v0.8.3 source referenced by the docsets still generated the older project. A user following this install gets no Applications sheet or the new aggregate config, so the rest of the tutorial does not match. Use a release/source install that contains the new generator, or keep this tutorial on the v0.8.3 sample.

Useful? React with 👍 / 👎.

Comment on lines +62 to +63
Only liveness and readiness probes and public verification-key discovery are served without
authentication.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document public OpenAPI in the unauthenticated surface

The security overview says only probes and JWKS discovery are unauthenticated, but the generated Relay and Notary configs set server.openapi_requires_auth: false, and registryctl smoke explicitly checks /openapi.json anonymously. In generated/default local deployments the docs/OpenAPI surface is public too, so this understates the unauthenticated surface operators need to account for. Qualify this as hardened deployments or list OpenAPI/docs alongside the probe/JWKS exceptions.

Useful? React with 👍 / 👎.

Comment on lines +82 to +86
python -m pip install "git+https://github.com/registrystack/registry-stack.git@vX.Y.Z#subdirectory=products/notary/bindings/python"
```

```bash
pnpm add "github:jeremi/registry-notary#vX.Y.Z&path:bindings/node"
pnpm add "github:registrystack/registry-stack#vX.Y.Z&path:products/notary/bindings/node"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update local install paths after moving to the monorepo

After these examples were switched to the registry-stack monorepo subdirectories, the fallback install instructions immediately below still use the old standalone layout (npm install ./bindings/node, /path/to/registry-notary/bindings/node, and /path/to/registry-notary/crates/...). Those paths do not exist in a registry-stack checkout, so npm users and local path users following this section fail before package installation. Update the fallback/local examples to use products/notary/bindings/... and the monorepo crate paths.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants